package com.mamahao.vmnetframework.framework.net.basis

import com.mamahao.vmnetframework.BuildConfig
import com.mamahao.vmnetframework.framework.net.adapter.CoroutineCallAdapterFactory
import com.mamahao.vmnetframework.framework.net.basis.code.HttpConfig
import com.mamahao.vmnetframework.framework.net.basis.interceptor.HeaderInterceptor
import com.mamahao.vmnetframework.framework.net.basis.interceptor.ParamsInterceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit

class RetrofitManagement {

    private val READ_TIMEOUT: Long = 6000

    private val WRITE_TIMEOUT: Long = 6000

    private val CONNECT_TIMEOUT: Long = 6000

    private val serviceMap = ConcurrentHashMap<String, Any>()

    companion object {
        internal val instance: RetrofitManagement by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            RetrofitManagement()
        }

        @JvmStatic
        fun getInstance(): RetrofitManagement {
            return RetrofitManagement.instance
        }
    }

    private fun createRetrofit(url: String): Retrofit {
        val builder = OkHttpClient.Builder()
                .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
                .writeTimeout(WRITE_TIMEOUT, TimeUnit.MILLISECONDS)
                .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS)
//                .addInterceptor(HttpInterceptor())
                .addInterceptor(ParamsInterceptor())
                .addInterceptor(HeaderInterceptor())
                .retryOnConnectionFailure(true)
        if (BuildConfig.DEBUG) {
            val httpLoggingInterceptor = HttpLoggingInterceptor()
            httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
            builder.addInterceptor(httpLoggingInterceptor)
        }
        val client = builder.build()
        return Retrofit.Builder()
                .client(client)
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(CoroutineCallAdapterFactory())
                .build()
    }

    fun <T> getService(clz: Class<T>): T {
        return getService(clz, HttpConfig.BASE_URL)
    }

    @Throws(ClassCastException :: class)
    fun <T> getService(clz: Class<T>, host: String): T {
        val value: T
        if (serviceMap.containsKey(host)) {
            val obj = serviceMap[host]
            if (obj == null) {
                value = createRetrofit(host).create(clz)
                serviceMap[host] = value as Any
            } else {
                value = obj as T
            }
        } else {
            value = createRetrofit(host).create(clz)
            serviceMap[host] = value as Any
        }
        return value
    }

}